/**
 * Rxh 2010-12-28修改：支持实体关联属性排序，排序的字段必须是 selectEd 字段，但在select 后加入关联的字段
 * 会使query.list()的返回结果不能直接转换成 List<T>。需要手动修改一遍。
 */
package com.gosophia.commons.persistence;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.hibernate.exception.GenericJDBCException;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.util.JDBCExceptionReporter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;

import com.gosophia.commons.DateTranslate;
import com.gosophia.commons.OrderCondition;
import com.gosophia.commons.Page;
import com.gosophia.commons.PropertyFilter;
import com.gosophia.commons.PropertyFilter.OperatorType;
import com.gosophia.commons.PropertyFilter.ParamValueType;
import com.gosophia.commons.exception.BusinessException;
import com.gosophia.commons.exception.ConcurrencyException;
import com.gosophia.commons.exception.ExceptionDetail;

/**
 * Hibernat DAO泛型工具类.
 * 
 * 包含常用的增删改查、分页查询操作.
 * 
 * @param <T>
 *            DAO操作的对象类型
 * @param <PK>
 *            主键类型
 * 
 * @author zhangdongsheng
 */
@SuppressWarnings("deprecation")
public class HibernateRepository<T, PK extends Serializable> implements
        EntityRepository<T, PK> {

    protected Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    protected SessionFactory sessionFactory;

    protected Class<T> entityClass;

    protected String getEntityClassSimpleName() {
        return entityClassSimpleName;
    }

    protected String entityClassSimpleName;

    public HibernateRepository() {

    }

    public void setEntityClassInfo(Class<T> entityClass,
            String entityClassSimpleName) {
        this.entityClass = entityClass;
        this.entityClassSimpleName = entityClassSimpleName;
    }

    /**
     *构造函数
     */
    public HibernateRepository(final SessionFactory sessionFactory,
            final Class<T> entityClass) {
        this.sessionFactory = sessionFactory;
        this.entityClass = entityClass;
    }

    /**
     * 获取sessionFactory
     * 
     * @see com.gosophia.commons.Repository#getSessionFactory()
     */
    protected SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    /**
     * 设定sessionFactory 使用spring框架的情况下，此处使用自动注入的方式
     * 
     * @seecom.gosophia.commons.Repository#setSessionFactory(org.hibernate.
     */
    protected void setSessionFactory(final SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    /**
     * 获取当前session
     * 
     * @see com.gosophia.commons.Repository#getSession()
     */
    public Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    // ------Add by Rxh 2010/07/05 Start------Code Review 2010/06/25-------
    /**
     * 新增
     * 
     * @param entity
     *            新增 实体
     * */
    public void save(final T entity) {
        Assert.notNull(entity, "entity不能为空");
        getSession().save(entity);
        logger.debug("save entity: {}", entity);
    }
    
    /**
     * 新增
     * 
     * @param entity
     *            新增 实体            
     * @return 主键
     */
    public Serializable add(final T entity) {
        Assert.notNull(entity, "entity不能为空");
        logger.debug("save entity: {}", entity);
        return getSession().save(entity);
    }

    /**
     * 更新实体，实体可以是游离态或持久态。 注意点：此updata内部使用merge实现，所以当被更新的实体已经不存在时会把当前的记录插入。
     * 如果需要保证不存在的记录不被更新，请使用update(final T entity,PK id)方法
     * 
     * @see <a >update(final T entity,PK id)</a>
     * @param entity
     *            需要更新的实体
     * 
     * */
    @SuppressWarnings("unchecked")
    public void update(final T entity) {
        Assert.notNull(entity, "entity不能为空");
        Class clazz = entity.getClass();
        ClassMetadata metaData = getSessionFactory().getClassMetadata(clazz);
        while(metaData == null) {
        	clazz = clazz.getSuperclass();
        	metaData = getSessionFactory().getClassMetadata(clazz);
        }
        PK id = (PK) getSessionFactory().getClassMetadata(clazz)
                .getIdentifier(entity, EntityMode.POJO);

        getSession().evict(getSession().load(clazz, id));
        getSession().update(entity);
        logger.debug("update entity: {}", entity);
    }

    /**
     * 
     * 更新实体指定的几个属性
     * 
     * @param id
     *            主键
     * @param version
     *            版本号
     * @param updatedParams
     *            要更新属性的键值对
     * @return 更新记录数
     */
    public void update(final PK id, Long version,
            Map<String, Object> updatedParams) {
        Assert.notNull(id, "id不能为空");
        Assert.notNull(updatedParams, "updatedParams不能为空");
        Assert.isTrue(updatedParams.size() > 0, "没有传入要更新的属性！");

        StringBuilder hql = new StringBuilder();
        hql.append("update ");
        hql.append(entityClass.getSimpleName());
        hql.append(" set ");

        Iterator<String> itKey = updatedParams.keySet().iterator();
        while (itKey.hasNext()) {
            String propertyName = itKey.next();
            hql.append(propertyName);
            hql.append("=:");
            hql.append(propertyName); // propertyName=:propertyName
            hql.append(",");
        }
        hql.deleteCharAt(hql.lastIndexOf(","));
        hql.append(" where ");
        hql.append(getIdName());
        hql.append("=:id and version=:version");

        Query query = getSession().createQuery(hql.toString());

        itKey = updatedParams.keySet().iterator();
        while (itKey.hasNext()) {
            String propertyName = itKey.next();
            query.setParameter(propertyName, updatedParams.get(propertyName));
        }

        query.setParameter("id", id);
        query.setParameter("version", version);

        // try {
        // query.executeUpdate();
        // } catch (Exception e) {
        // throw new
        // RuntimeException("update(final PK id, Long version, Map<String, Object> updatedParams) method "
        // +
        // "can't execute,id is:"+ id , e);
        // }
        try {
            int count = query.executeUpdate();
            if (count == 0) {
                throw new RuntimeException("id or version is error");
            }
        }  catch (Exception e) {
            throw new ConcurrencyException(
                    "update(final PK id, Long version, Map<String, Object> updatedParams) method "
                            + "can't execute,id is:" + id, new ExceptionDetail(
                            "JC2_CP_C_1", ""));
        }
        logger.debug("update entity {},id is {}", entityClass.getSimpleName(),
                id);
    }

    /*
     * 根据Id删除实体
     */
    @Override
    public void delete(PK id) {
        Assert.notNull(id, "id不能为空");
        try {
            delete(load(id));
        } catch (Exception e) {
            throw new RuntimeException(
                    "delete(PK id) method can't execute,the parameter is:" + id,
                    e);
        }
        logger.debug("delete entity {},id is {}", entityClass.getSimpleName(),
                id);

    }

    /**
     * 删除实体
     * 
     * @param id
     *            实体Id
     * @param version
     *            实体版本号
     * */
    public void delete(final PK id, Long version) {
        Assert.notNull(id, "id不能为空");
        Assert.notNull(version, "version不能为空");
        StringBuilder hql = new StringBuilder();
        hql.append("delete ");
        hql.append(entityClass.getSimpleName());
        hql.append(" e where e.");
        hql.append(getIdName());
        hql.append("=? and e.version=?");

        Query query = getSession().createQuery(hql.toString());

        query.setParameter(0, id);
        query.setParameter(1, version);
        try {
            int count = query.executeUpdate();
            if (count == 0) {
                throw new RuntimeException("id or version error");
            }
        }catch (GenericJDBCException e) {
            throw new ConcurrencyException("该对象正被引用，不能删除", "JC2_CP_C_4");
        }catch (Exception e) {
            throw new ConcurrencyException(
                    "delete(final PK id, Long version) method can't execute,the parameter is:"
                            + id + "," + version, new ExceptionDetail(
                            "JC2_CP_C_3", ""));
        }
        logger.debug("delete entity {},id is {}", entityClass.getSimpleName(),
                id);

    }

    /**
     * 删除实体对象，实体可以是持久态或游离态
     * 
     * @param entity
     *            需要被删除实体
     * @see com.gosophia.commons.Repository#delete(T)
     */
    public void delete(final T entity) {
        Assert.notNull(entity, "entity不能为空");
        getSession().delete(entity);
        logger.debug("delete entity: {}", entity);
    }

    /**
     * 根据实体Id获取实体对象
     * 
     * @param id
     *            实体Id
     * @see com.gosophia.commons.Repository#get(PK)
     */
    @SuppressWarnings("unchecked")
    public T get(final PK id) {
        Assert.notNull(id, "id不能为空");
        return (T) getSession().get(entityClass, id);
    }

    // 新增 2010-09-27
    @SuppressWarnings("unchecked")
    private T load(final PK id) {
        Assert.notNull(id, "id不能为空");
        return (T) getSession().load(entityClass, id);
    }

    /**
     * 执行没有返回值的NamedQuery
     * 
     * @param queryName
     *            名称
     * @param values
     *            参数集合
     */
    public void executeNamedQuery(final String queryName,
            final Object... values) {
        Assert.hasText(queryName, "queryName不能为空");
        Query query = getSession().getNamedQuery(queryName);
        if (values != null) {
            for (int i = 0; i < values.length; i++) {
                query.setParameter(i, values[i]);
            }
        }
        query.executeUpdate();
    }

    /**
     * 执行没有返回值的NamedQuery
     * 
     * @param queryName
     *            名称
     * @param values
     *            参数集合
     */
    public void executeNamedQuery(final String queryName,
            final Map<String, Object> values) {
        Assert.hasText(queryName, "queryName不能为空");
        Query query = getSession().getNamedQuery(queryName);
        if (values != null) {
            query.setProperties(values);
        }
        query.executeUpdate();
    }

    /**
     * 根据 namedQuery的名称 进行查询
     * 
     * @param queryName
     *            命名查询
     * @param values
     *            命名查询的参数值 ，参数可以为0或多个
     * 
     * 
     * @see com.gosophia.commons.Repository#find(java.lang.String,
     *      java.util.Map)
     */
    @SuppressWarnings("unchecked")
    public <X> List<X> findListByNamedQuery(final String queryName,
            final Object... values) {
        Query query = getSession().getNamedQuery(queryName);

        if (values != null) {
            for (int i = 0; i < values.length; i++) {
                query.setParameter(i, values[i]);
            }
        }
        return query.list();
    }

    /**
     * 根据namedQuery 名称 查询唯一的实体
     * 
     * @param queryName
     *            命名查询的名称
     *@param values
     *            命名查询参数，参数可为0或多个
     * @see com.gosophia.commons.Repository#findUnique(java.lang.String,
     *      java.util.Map)
     */
    @SuppressWarnings("unchecked")
    public <X> X findUniqueByNamedQuery(final String queryName,
            final Object... values) {
        Query query = getSession().getNamedQuery(queryName);

        if (values != null) {
            for (int i = 0; i < values.length; i++) {
                query.setParameter(i, values[i]);
            }
        }
        return (X) query.uniqueResult();
    }

    /**
     * 根据namedQuery 进行查询
     * 
     * @param queryName
     *            已定义的namedQuery名称
     * @param value
     *            命名查询的参数 Map集合
     * @see com.gosophia.commons.Repository#find(java.lang.String,
     *      java.util.Map)
     */
    @SuppressWarnings("unchecked")
    public <X> List<X> findListByNamedQuery(final String queryName,
            final Map<String, Object> values) {
        Query query = getSession().getNamedQuery(queryName);

        if (values != null) {
            query.setProperties(values);
        }
        return query.list();
    }

    /**
     * 根据命名查询唯一的对象
     * 
     * @param queryName
     *            已定以命名查询的名称
     * @param values
     *            命名查询的参数
     * @see com.gosophia.commons.Repository#findUnique(java.lang.String,
     *      java.util.Map)
     */
    @SuppressWarnings("unchecked")
    public <X> X findUniqueByNamedQuery(final String queryName,
            final Map<String, Object> values) {
        Query query = getSession().getNamedQuery(queryName);

        if (values != null) {
            query.setProperties(values);
        }
        return (X) query.uniqueResult();
    }

    /**
     * 使用 hql 查询列表数据
     * 
     * @see com.gosophia.commons.Repository#find(java.lang.String,
     *      java.lang.Object)
     */
    @SuppressWarnings("unchecked")
    public <X> List<X> findListByHql(final String hql, final Object... values) {
        return createQuery(hql, values).list();
    }

    /**
     * 使用 hql 查询列表数据
     * 
     * @see com.gosophia.commons.Repository#find(java.lang.String,
     *      java.util.Map)
     */
    @SuppressWarnings("unchecked")
    public <X> List<X> findListByHql(final String hql,
            final Map<String, Object> values) {
        return createQuery(hql, values).list();
    }

    /**
     * 使用hql查询唯一的数据项
     * 
     * @see com.gosophia.commons.Repository#findUnique(java.lang.String,
     *      java.lang.Object)
     */
    @SuppressWarnings("unchecked")
    public <X> X findUniqueByHql(final String hql, final Object... values) {
        return (X) createQuery(hql, values).uniqueResult();
    }

    /**
     * 使用hql查询唯一的数据项
     * 
     * @param hql
     *            hql查询字符串
     * @param param
     *            查询参数名称
     *@param value
     *            查询参数值
     * @see com.gosophia.commons.Repository#findUnique(java.lang.String,
     *      java.util.Map)
     */
    @SuppressWarnings("unchecked")
    public <X> X findUniqueByHql(final String hql, final String param,
            final String value) {
        return (X) createQuery(hql, param, value).uniqueResult();
    }

    @SuppressWarnings("unchecked")
    public <X> X findUniqueByHql(final String hql,
            final Map<String, Object> values) {
        return (X) createQuery(hql, values).uniqueResult();
    }

    /**
     * 创建hql Query对象
     * 
     * @param queryString
     *            hql查询字符串
     * @param values
     *            参数列表
     * @see com.gosophia.commons.Repository#createQuery(java.lang.String,
     *      java.lang.Object)
     */
    public Query createQuery(final String queryString, final Object... values) {
        Assert.hasText(queryString, "queryString不能为空");
        Query query = getSession().createQuery(queryString);
        if (values != null) {
            for (int i = 0; i < values.length; i++) {
                query.setParameter(i, values[i]);
            }
        }
        return query;
    }

    /**
     * 创建Hql查询Query对象
     * 
     * @param queryString
     *            hql查询字符串
     * @param values
     *            参数集合
     * @see com.gosophia.commons.Repository#createQuery(java.lang.String,
     *      java.util.Map)
     */
    public Query createQuery(final String queryString,
            final Map<String, Object> values) {
        Assert.hasText(queryString, "queryString不能为空");
        Query query = getSession().createQuery(queryString);
        if (values != null) {
            query.setProperties(values);
        }
        return query;
    }

    /**
     * 创建HQL查询
     * 
     * @param queryString
     *            hql查询字符串
     * @param param
     *            参数名称字符串
     * @param value
     *            参数值字符串
     * @see com.gosophia.commons.Repository#createQuery(java.lang.String,
     *      java.util.Map)
     */
    public Query createQuery(final String queryString, final String param,
            final String value) {
        Assert.hasText(queryString, "queryString不能为空");
        Query query = getSession().createQuery(queryString);
        if (value != null) {
            query.setString(param, value);
        }
        return query;
    }

    /**
     * 强制加载实体，hibenate立即去数据库加载数据
     * 
     * @param entity
     *            需要被强制加载的实体
     * @see com.gosophia.commons.Repository#initEntity(T)
     */
    protected void initEntity(T entity) {
        Hibernate.initialize(entity);
    }

    /**
     * 强制加载实体列表，hibernate立即去数据库加载数据
     * 
     * @param entityList
     *            实体列表
     * @see com.gosophia.commons.Repository#initEntity(java.util.List)
     */
    protected void initEntity(List<T> entityList) {
        for (T entity : entityList) {
            Hibernate.initialize(entity);
        }
    }

    /**
     * 返回实体的Identifier属性名称
     * 
     * @see com.gosophia.commons.Repository#getIdName()
     */
    private String getIdName() {
        ClassMetadata meta = getSessionFactory().getClassMetadata(entityClass);
        return meta.getIdentifierPropertyName();
    }

    /*-------------批量处理---------------------------------------------------------------------*/

    /**
     * 批量处理方法
     * 
     * @param hql
     *            hql语句字符串
     * @param value
     *            0或多个参数
     * @see com.gosophia.commons.Repository#batchExecute(java.lang.String,
     *      java.lang.Object)
     */
    public int batchExecute(final String hql, final Object... values) {
        return createQuery(hql, values).executeUpdate();
    }

    /**
     * 批量执行
     * 
     * 
     * @see com.gosophia.commons.Repository#batchExecute(java.lang.String,
     *      java.util.Map)
     */
    public int batchExecute(final String hql, final Map<String, Object> values) {
        return createQuery(hql, values).executeUpdate();
    }

    /**
     * 使用命名查询的方式进行分页查询
     * 
     * @param page
     *            查询page，封装了分页参数设定
     * @param queryName
     *            已定以命名查询，hql的格式为 from ClassName where propertyName1 = ? and
     *            propertyName2 = ?
     * @param values
     *            可变参数，需要参照查询字符串中参数的位置
     * @return
     */
    @SuppressWarnings("unchecked")
    public Page<T> findPageByNamedQuery(final Page<T> page,
            final String queryName, final Object... values) {
        Assert.notNull(page, "page不能为空");

        Query q = getSession().getNamedQuery(queryName);

        if (page.isAutoCount()) {
            long totalCount = countHqlResult(q.getQueryString(), values);
            page.setTotalCount(totalCount);
        }

        if (values != null) {
            for (int i = 0; i < values.length; i++) {
                q.setParameter(i, values[i]);
            }
        }

        setPageParameter(q, page);
        // List result = q.list();
        // page.setResult(result);
        // ------start-----------------------------------------------
        // Rxh 2010-12-28修改：支持实体关联属性排序，排序的字段必须是 selectEd 字段，但在select 后加入关联的字段
        // 会使query.list()的返回结果不能直接转换成 List<T>。需要手动修改一遍。
        List result = q.list();

        List<T> rslt = new ArrayList<T>();

        for (Object oArr : result) {
            if (oArr instanceof Object[]) {
                for (Object e : (Object[]) oArr) {
                    if (e.getClass().equals(entityClass)) {
                        rslt.add((T) e);
                    }
                }
            } else {
                if (oArr.getClass().equals(entityClass)) {
                    rslt.add((T) oArr);
                }
            }
        }
        page.setResult(rslt);
        // -------end-------------------------------------------
        return page;
    }

    /**
     * 使用命名查询的方式进行分页查询
     * 
     * @param page
     *            查询page，封装了分页参数设定
     * @param queryName
     *            已定以命名查询，hql的格式为 from ClassName where propertyName1 = ? and
     *            propertyName2 = ?
     * @param values
     *            可变参数，需要参照查询字符串中参数的位置
     * @return
     */
    @SuppressWarnings("unchecked")
    public Page<T> findPageByNamedQuery(final Page<T> page,
            final String queryName, List<OrderCondition> orderConditions,
            final Object... values) {
        Assert.notNull(page, "page不能为空");

        Query q = getOrderByQuery(queryName, orderConditions);

        if (page.isAutoCount()) {
            long totalCount = countHqlResult(q.getQueryString(), values);
            page.setTotalCount(totalCount);
        }

        if (values != null) {
            for (int i = 0; i < values.length; i++) {
                q.setParameter(i, values[i]);
            }
        }

        setPageParameter(q, page);
        // List result = q.list();
        // page.setResult(result);
        // ------start-----------------------------------------------
        // Rxh 2010-12-28修改：支持实体关联属性排序，排序的字段必须是 selectEd 字段，但在select 后加入关联的字段
        // 会使query.list()的返回结果不能直接转换成 List<T>。需要手动修改一遍。
        List result = q.list();

        List<T> rslt = new ArrayList<T>();

        for (Object oArr : result) {
            if (oArr instanceof Object[]) {
                for (Object e : (Object[]) oArr) {
                    if (e != null && e.getClass().equals(entityClass)) {
                        rslt.add((T) e);
                    }
                }
            } else {
                if (oArr.getClass().equals(entityClass)) {
                    rslt.add((T) oArr);
                }
            }
        }
        page.setResult(rslt);
        // -------end-------------------------------------------
        return page;
    }

    /**
     * 使用命名查询的方式进行分页查询
     * 
     * @param page
     *            分页查询对象 封装了分页参数设定
     * @param queryName
     *            已定义命名查询名称
     * @param values
     *            参数值
     * @param orderConditions
     *            排序条件
     * @return
     */
    @SuppressWarnings("unchecked")
    @Override
    public Page<T> findPageByNamedQuery(Page<T> page, String queryName,
            Map<String, Object> values, OrderCondition... orderConditions) {
        Assert.notNull(page, "page不能为空");

        Query q = getOrderByQuery(queryName, orderConditions);

        if (page.isAutoCount()) {
            long totalCount = countHqlResult(q.toString(), values);
            page.setTotalCount(totalCount);
        }
        if (values != null) {
            q.setProperties(values);
        }
        setPageParameter(q, page);
        // List<T> result = q.list();
        // page.setResult(result);

        // ------start-----------------------------------------------
        // Rxh 2010-12-28修改：支持实体关联属性排序，排序的字段必须是 selectEd 字段，但在select 后加入关联的字段
        // 会使query.list()的返回结果不能直接转换成 List<T>。需要手动修改一遍。
        List result = q.list();

        List<T> rslt = new ArrayList<T>();

        for (Object oArr : result) {
            if (oArr instanceof Object[]) {
                for (Object e : (Object[]) oArr) {
                    if (e != null && e.getClass().equals(entityClass)) {
                        rslt.add((T) e);
                    }
                }
            } else {
                if (oArr.getClass().equals(entityClass)) {
                    rslt.add((T) oArr);
                }
            }
        }
        page.setResult(rslt);
        // -------end-------------------------------------------
        return page;
    }

    /**
     * 使用命名查询的方式进行分页查询
     * 
     * @param page
     *            分页查询对象 封装了分页参数设定
     * @param queryName
     *            已定义命名查询名称
     * @param values
     *            参数值
     * @param orderConditions
     *            排序条件
     * @return
     */
    @Override
    public Page<T> findPageByNamedQuery(Page<T> page, String queryName,
            Map<String, Object> values, List<OrderCondition> orderConditions) {
        if (orderConditions == null) {
            return findPageByNamedQuery(page, queryName, values);
        } else {
            OrderCondition[] ords = new OrderCondition[orderConditions.size()];
            return findPageByNamedQuery(page, queryName, values,
                    orderConditions.toArray(ords));
        }
    }

    /**
     * 使用Hql进行分页查询
     * 
     * @param page
     *            分页查询对象 ，封装了分页查询参数
     * @param hql
     *            HQl查询字符串,hql格式为
     * @param values
     *            hql查询参数值，需要参照hql中的参数顺序
     * @return
     */
    @SuppressWarnings("unchecked")
    public Page<T> findPageByHql(final Page<T> page, final String hql,
            final Object... values) {
        Assert.notNull(page, "page不能为空");

        Query q = createQuery(hql, values);
        if (page.isAutoCount()) {
            long totalCount = countHqlResult(hql, values);
            page.setTotalCount(totalCount);
        }
        if (values != null) {
            for (int i = 0; i < values.length; i++) {
                q.setParameter(i, values[i]);
            }
        }
        setPageParameter(q, page);
        // List result = q.list();
        // page.setResult(result);

        // ------start-----------------------------------------------
        // Rxh 2010-12-28修改：支持实体关联属性排序，排序的字段必须是 selectEd 字段，但在select 后加入关联的字段
        // 会使query.list()的返回结果不能直接转换成 List<T>。需要手动修改一遍。
        List result = q.list();

        // Rxh 2011-04-28修改，元数据select new map()，返回结果为Map形式
        if (entityClass == null){
        	page.setResult(result);
        	return page;
        }
        
        List<T> rslt = new ArrayList<T>();

        for (Object oArr : result) {
            if (oArr instanceof Object[]) {
                for (Object e : (Object[]) oArr) {
                    if (e != null && e.getClass().equals(entityClass)) {
                        rslt.add((T) e);
                    }
                }
            } else {
                if (oArr.getClass().equals(entityClass)) {
                    rslt.add((T) oArr);
                }
            }
        }
        page.setResult(rslt);
        // -------end-------------------------------------------

        return page;
    }

    /**
     * 使用Hql进行分页查询
     * 
     * @param page
     *            分页查询对象 ，封装了分页查询参数
     * @param hql
     *            HQl查询字符串,hql 格式为：from ClassName where propertyName1
     *            =:propertyName1 and propertyName2 =:propertyName2
     * @param values
     *            hql查询参数值
     * @return
     */
    @SuppressWarnings("unchecked")
    public Page<T> findPageByHql(final Page<T> page, final String hql,
            final Map<String, Object> values) {
        Assert.notNull(page, "page不能为空");

        Query q = createQuery(hql, values);

        if (page.isAutoCount()) {
            long totalCount = countHqlResult(hql, values);
            page.setTotalCount(totalCount);
        }
        q.setProperties(values);
        setPageParameter(q, page);

        // List result = q.list();
        // page.setResult(result);

        // ------start-----------------------------------------------
        // Rxh 2010-12-28修改：支持实体关联属性排序，排序的字段必须是 selectEd 字段，但在select 后加入关联的字段
        // 会使query.list()的返回结果不能直接转换成 List<T>。需要手动修改一遍。
        List result = q.list();

        // Rxh 2011-04-28修改，元数据select new map()，返回结果为Map形式
        if (entityClass == null){
        	page.setResult(result);
        	return page;
        }
        
        List<T> rslt = new ArrayList<T>();

        for (Object oArr : result) {
            if (oArr instanceof Object[]) {
                for (Object e : (Object[]) oArr) {
                    if (e != null && e.getClass().equals(entityClass)) {
                        rslt.add((T) e);
                    }
                }
            } else {
                if (oArr.getClass().equals(entityClass)) {
                    rslt.add((T) oArr);
                }
            }
        }
        page.setResult(rslt);
        // -------end-------------------------------------------

        return page;
    }

    /**
     * 使用hql进行分页查询，使用单一参数
     * 
     * @param page
     *            分页查询对象 ，封装了分页查询参数
     * @param hql
     *            HQl查询字符串，推荐使用具名参数查询，hql格式举例：from ClassName where propertyName1
     *            =:propertyName1 and propertyName2 =:propertyName2
     * @param parame
     *            参数名称
     * @param values
     *            参数值
     * @return
     */
    @SuppressWarnings("unchecked")
    public Page<T> findPageByHql(final Page<T> page, final String hql,
            final String paraName, final String values) {
        Assert.notNull(page, "page不能为空");

        Query q = createQuery(hql, paraName, values);

        if (page.isAutoCount()) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put(paraName, values);

            long totalCount = countHqlResult(hql, map);
            page.setTotalCount(totalCount);
        }

        setPageParameter(q, page);

        // List result = q.list();
        // page.setResult(result);

        // ------start-----------------------------------------------
        // Rxh 2010-12-28修改：支持实体关联属性排序，排序的字段必须是 selectEd 字段，但在select 后加入关联的字段
        // 会使query.list()的返回结果不能直接转换成 List<T>。需要手动修改一遍。
        List result = q.list();

        List<T> rslt = new ArrayList<T>();

        for (Object oArr : result) {
            if (oArr instanceof Object[]) {
                for (Object e : (Object[]) oArr) {
                    if (e != null && e.getClass().equals(entityClass)) {
                        rslt.add((T) e);
                    }
                }
            } else {
                if (oArr.getClass().equals(entityClass)) {
                    rslt.add((T) oArr);
                }
            }
        }
        page.setResult(rslt);
        // -------end-------------------------------------------
        return page;
    }

    /**
     * 设置分页参数到Query对象,辅助函数.
     */
    protected Query setPageParameter(final Query q, final Page<T> page) {

        q.setFirstResult(page.getFirst() - 1);
        q.setMaxResults(page.getPageSize());
        return q;
    }

    /**
     * 执行count查询获得本次Hql查询所能获得的对象总数. 本函数只能自动处理简单的hql语句,复杂的hql查询请另行编写count语句查询.
     */
    public long countHqlResult(final String hql,
            final Map<String, Object> values) {
        String fromHql = hql;
        String distinctStr = "";

        // 抽取distinct子句    
        distinctStr = StringUtils.substringBefore(fromHql, "from");
        distinctStr = StringUtils.substringAfter(distinctStr, "select");

        // select子句与order by子句会影响count查询,进行简单的排除.
        fromHql = "from " + StringUtils.substringAfter(fromHql, "from");
        fromHql = StringUtils.substringBefore(fromHql, "order by");

        // 根据情况添加distinct子句
        String countHql;
        //(Modified by Rxh 2011-4-27, 当hql中含有Group by,New Map,New [Entity] 或聚集函数时，
        //使用 count(*))
        if (distinctStr.trim().toUpperCase().startsWith("DISTINCT")){
        	distinctStr = StringUtils.substringBefore(distinctStr, ",");
            countHql = "select count(" + distinctStr + ") " + fromHql;
        }else {
            countHql = "select count(*) " + fromHql;
        }

        try {
            Long count = findUniqueByHql(countHql, values);
            return count;
        } catch (Exception e) {
            throw new RuntimeException("hql can't be auto count, hql is:"
                    + countHql, e);
        }
    }

    /**
     * 执行count查询获得本次Hql查询所能获得的对象总数. 本函数只能自动处理简单的hql语句,复杂的hql查询请另行编写count语句查询.
     */
    public long countHqlResult(final String hql, final Object... values) {
        String fromHql = hql;
        String distinctStr;

        // 抽取distinct子句
        distinctStr = StringUtils.substringBefore(fromHql, "from");
        distinctStr = StringUtils.substringAfter(distinctStr, "select");

        // select子句与order by子句会影响count查询,进行简单的排除.
        fromHql = "from " + StringUtils.substringAfter(fromHql, "from");
        fromHql = StringUtils.substringBefore(fromHql, "order by");

        // 根据情况添加distinct子句
        String countHql;
        //(Modified by Rxh 2011-4-27, 当hql中含有Group by,New Map,New [Entity] 或聚集函数时，
        //使用 count(*))
        if (distinctStr.trim().toUpperCase().startsWith("DISTINCT")){
        	distinctStr = StringUtils.substringBefore(distinctStr, ",");
            countHql = "select count(" + distinctStr + ") " + fromHql;
        }else {
            countHql = "select count(*) " + fromHql;
        }

        try {
            Long count = findUniqueByHql(countHql, values);
            return count;
        } catch (Exception e) {
            throw new RuntimeException("hql can't be auto count, hql is:"
                    + countHql, e);
        }
    }

    /**
     * 根据namedQuery形式查询记录数，形式为 name :value
     * 
     * @param queryName
     * @param values
     * @return
     */
    public long countNamedQueryResult(final String queryName,
            final Map<String, Object> values) {
        Assert.notNull(values, "value不能为空");
        Query q = getSession().getNamedQuery(queryName);
        if (values != null) {
            q.setProperties(values);
        }
        long totalCount = (Long) q.uniqueResult();
        return totalCount;
    }

    /**
     * 根据namedQuery形式查询记录数，形式参照 property =?
     * 
     * @param queryName
     * @param values
     * @return
     */
    public long countNamedQueryResult(final String queryName,
            final Object... values) {
        Query q = getSession().getNamedQuery(queryName);
        if (values != null) {
            for (int i = 0; i < values.length; i++) {
                q.setParameter(i, values[i]);
            }
        }
        long totalCount = (Long) q.uniqueResult();
        return totalCount;
    }
    /** 根据属性,排序条件查询,返回列表    wangxinbing 11.03.03*/
    //ADD
    public List<T> findListByProperties(List<PropertyFilter> propertyFilters,
            OrderCondition... orderConditions){
        //TODO
        List<OrderCondition> orderList = new ArrayList<OrderCondition>();

        if (orderConditions != null) {
            for (OrderCondition order : orderConditions) {
                orderList.add(order);
            }
        }
        return findListByProperties(propertyFilters,orderList);
    }
    
    public List<T> findListByProperties(List<PropertyFilter> propertyFilters,
            List<OrderCondition> orderConditions){
        //TODO
        StringBuilder queryString = new StringBuilder();

        PropertyFilter[] propertyFilterArr = null;
        if (null != propertyFilters) {
            propertyFilterArr = new PropertyFilter[propertyFilters.size()];
            propertyFilterArr = propertyFilters.toArray(propertyFilterArr);
        }
        queryString.append(getEntireHqlByPropertyAndOrder(true,
                propertyFilters, orderConditions));
        return this.findListByHql(queryString.toString(),
                HibernateRepository.getNameHqlParam2(propertyFilterArr));
    }
    //END


    /** 根据属性进行过滤 分页查询 */
    /*
     * edit by zhangds 2010-10-27 修改：添加了对or的支持，把orFilters中的过滤条件提取出来
     */
    public Page<T> findPageByProperties(Page<T> page,
            List<PropertyFilter> propertyFilters,
            OrderCondition... orderConditions) {

        List<OrderCondition> orderList = new ArrayList<OrderCondition>();

        if (orderConditions != null) {
            for (OrderCondition order : orderConditions) {
                orderList.add(order);
            }
        }
        page = findPageByProperties(page, propertyFilters, orderList);
        return page;
    }

    /** 根据属性进行过滤 并排序分页查询 */
    public Page<T> findPageByProperties(Page<T> page,
            List<PropertyFilter> propertyFilters,
            List<OrderCondition> orderConditions) {

        StringBuilder queryString = new StringBuilder();
        // queryString.append("select distinct _e from ").append(getEntityClassSimpleName());

        PropertyFilter[] propertyFilterArr = null;
        if (null != propertyFilters) {
            propertyFilterArr = new PropertyFilter[propertyFilters.size()];
            propertyFilterArr = propertyFilters.toArray(propertyFilterArr);
        }

        // queryString.append(
        // changePropertyAndOrderToHqlByFlag(true, propertyFilters,
        // orderConditions));

        queryString.append(getEntireHqlByPropertyAndOrder(true,
                propertyFilters, orderConditions));

        // 排序条件不为空时，添加排序
        page = this.findPageByHql(page, queryString.toString(),
                HibernateRepository.getNameHqlParam2(propertyFilterArr));
        return page;
    }

    /**
     * 全字段模糊搜索，搜索范围为实体上标注了@ShowItem或者@SearchEnable标注的属性
     * 
     * @throws BusinessException
     *             当没有指定模糊匹配列时，抛出异常
     * */
    public Page<T> allFiledSearching(Page<T> page, String searchStr,
            String dateFormat, OrderCondition... orderConditions) {

        if (orderConditions == null || orderConditions.length < 0) {
            return allFiledSearching(page, searchStr);
        } else {
            List<OrderCondition> ords = new ArrayList<OrderCondition>();
            for (OrderCondition ord : orderConditions) {
                ords.add(ord);
            }
            return allFiledSearching(page, searchStr, ords);
        }
    }

    /**
     * 全字段模糊搜索，搜索范围为实体上标注了@ShowItem标注的属性
     * 
     * @throws BusinessException
     *             当没有指定模糊匹配列时，抛出异常
     * */
    @Deprecated
    public Page<T> allFiledSearching(Page<T> page, String searchStr,
            String orderbyStr, String orderbyFlg) {

        Boolean ascending = (orderbyFlg == null || orderbyFlg
                .equalsIgnoreCase("ASC")) ? true : false;

        OrderCondition order = null;
        if (orderbyStr == null) {
            order = new OrderCondition(orderbyStr, ascending);
        }

        // 获取所有属性的类别
        return allFiledSearching(page, searchStr, "yyyy-mm-dd", order);
    }

    @Override
    public Page<T> allFiledSearching(Page<T> page, String searchStr,
            List<OrderCondition> orderConditions) {
        return allFiledSearching(page, searchStr, null, orderConditions);
    }

    @Override
    public Page<T> allFiledSearching(Page<T> page, String searchStr,
            String dateFormat, List<OrderCondition> orderConditions) {
        return allFiledSearching(page, searchStr, dateFormat,
                new ArrayList<PropertyFilter>(), orderConditions);
    }

  //将@SearchEnabled（单个属性）转换成 模糊查询 PropertyFilter;
	private PropertyFilter getPropertyFilterBySearchEnable(SearchEnable searchEnable, String searchStr, String defaultName){
		String searchProperty = "";
		String toCharFormat = "";

		searchProperty = searchEnable.searchProperty();
		if (searchProperty == null || searchProperty.isEmpty()) {
			searchProperty = defaultName;
		}
		
		toCharFormat = searchEnable.toCharFormat();
		if (toCharFormat == null || toCharFormat.isEmpty()) {
			toCharFormat = "none";
		}
		
		PropertyFilter pf = new PropertyFilter(searchProperty, OperatorType.LIKE,
				searchStr);
		pf.setToCharFormat(toCharFormat);
		
		return pf;
	}
	
	/**
	 * Modified by Rxh 2011-01-19
	 * 支持 @SearchEnabled（单个属性）、@JoinSearchItems（关联的多个子属性）两种标注
	 */
	@Override
	public Page<T> allFiledSearching(Page<T> page, String searchStr,
			String dateFormat, List<PropertyFilter> propertyFilters,
			List<OrderCondition> orderConditions) {
		StringBuilder hql = new StringBuilder();

		if (dateFormat == null) {
			dateFormat = "yyyy-mm-dd";
		}

		if (searchStr == null) {
			searchStr = "";
		}

		// 参数名字
		// String param = "condition";
		//
		// String value = "";
		// 获取全部的实体
		// Field[] allProperties = entityClass.getDeclaredFields();
		Field[] entityProperties = entityClass.getDeclaredFields();
		// 新增 王新兵 2010-11-30
		Field[] superProperties = entityClass.getSuperclass()
				.getDeclaredFields();
		Field[] allProperties = new Field[entityProperties.length
				+ superProperties.length];
		java.lang.System.arraycopy(superProperties, 0, allProperties, 0,
				superProperties.length);
		java.lang.System.arraycopy(entityProperties, 0, allProperties,
				superProperties.length, entityProperties.length);
		// END

		// hql.append("select distinct _e from ").append(entityClassSimpleName);

		PropertyFilter pf = null;
		List<PropertyFilter> pfs;
		if (propertyFilters == null) {
			pfs = new ArrayList<PropertyFilter>();
		} else {
			pfs = propertyFilters;
		}

		//查找模糊排序标记：支持 @SearchEnabled（单个属性）、@JoinSearchItems（关联的多个子属性）两种标注
		for (Field field : allProperties) {
			
			//@JoinSearchItems（关联的多个子属性）
			if (field != null && field.isAnnotationPresent(JoinSearchItems.class)){
				for (SearchEnable searchEnable : field.getAnnotation(JoinSearchItems.class).searchEnables()){
					if (pf == null) {
						pf = getPropertyFilterBySearchEnable(searchEnable, searchStr, field.getName());
					} else {
						PropertyFilter newPf = getPropertyFilterBySearchEnable(searchEnable, searchStr, field.getName());
						pf = pf.or(newPf);
					}
				}
			} 
			//@SearchEnabled（单个属性）
			else if (field != null && (field.isAnnotationPresent(SearchEnable.class))) {
				SearchEnable searchEnable = field.getAnnotation(SearchEnable.class);
				if (pf == null) {
					pf = getPropertyFilterBySearchEnable(searchEnable, searchStr, field.getName());
				} else {
					PropertyFilter newPf = getPropertyFilterBySearchEnable(searchEnable, searchStr, field.getName());
					pf = pf.or(newPf);
				}
			}
		}
		
		if (pf != null) {
			pfs.add(pf);
		}

		hql.append(getEntireHqlByPropertyAndOrder(true, pfs, orderConditions));

		PropertyFilter[] pfArr = null;
		if (!pfs.isEmpty()) {
			pfArr = new PropertyFilter[pfs.size()];
			pfArr = pfs.toArray(pfArr);
		}

		// 获取所有属性的类别
		return findPageByHql(page, hql.toString(), getNameHqlParam2(pfArr));
	}

    @Override
    public Page<T> allFiledSearching(Page<T> page, String searchStr,
            OrderCondition... orderConditions) {
        return allFiledSearching(page, searchStr, "yyyy-mm-dd", orderConditions);
    }

    /**
     * 根据实体Id列表获取实体列表
     */
    @Override
    public List<T> findByIds(List<PK> ids) {
        String hql = "from " + getEntityClassSimpleName() + " where "
                + getIdName() + " in (:ids)";

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("ids", ids);
        return findListByHql(hql, map);
    }

    /**
     * 分页查询
     * 
     * @param page
     *            分页参数
     */
    @SuppressWarnings("unchecked")
    @Override
    public Page<T> findPage(Page<T> page, List<OrderCondition> orderConditions) {
        StringBuilder strB = new StringBuilder();
        strB.append("from ").append(getEntityClassSimpleName())
                .append(
                        changePropertyAndOrderToHqlByFlag(false, null,
                                orderConditions));
        String hql = strB.toString();

        Query queryAll = createQuery(hql);

        page.setTotalCount(countHqlResult(hql));
        page.setResult(setPageParameter(queryAll, page).list());
        return page;
    }

    /**
     * 分页查询
     * 
     * @param page
     *            分页参数
     */
    @Override
    public Page<T> findPage(Page<T> page, OrderCondition... orderConditions) {
        List<OrderCondition> orders = new ArrayList<OrderCondition>();
        if (orderConditions != null) {
            for (OrderCondition order : orderConditions) {
                orders.add(order);
            }
        }
        return findPage(page, orders);
    }

    /**
     * 获取全部的对象　
     * 
     */
    @SuppressWarnings("unchecked")
    @Override
    public List<T> getAll() {
        String hql = "from " + getEntityClassSimpleName();
        Query queryAll = createQuery(hql);
        return queryAll.list();
    }

    /**
     * 根据属性查找实体列表，过滤条件为属性值相等
     */
    @SuppressWarnings("unchecked")
    @Override
    public List<T> findByProperties(Map<String, Object> properties) {
        StringBuilder hql = new StringBuilder().append("from "
                + getEntityClassSimpleName());
        if (properties.keySet().size() != 0) {
            hql.append(" where ");
            Iterator<String> it = properties.keySet().iterator();
            while (it.hasNext()) {
                String propertyName = it.next();
                hql.append(propertyName + " =:" + propertyName);
                hql.append(" and ");
            }
            hql.delete(hql.length() - " and ".length(), hql.length() - 1);
        }
        Query query = createQuery(hql.toString(), properties);
        return query.list();
    }

    /**
     * 根据属性查询实体列表
     * 
     * @param propertyName
     *            属性名称
     * @param value
     *            属性值
     */
    @SuppressWarnings("unchecked")
    @Override
    public List<T> findByProperty(String propertyName, Object value) {
        StringBuilder hql = new StringBuilder().append("from "
                + getEntityClassSimpleName() + " where ");
        hql.append(propertyName + " =?");
        return createQuery(hql.toString(), value).list();
    }

    /**
     * 根据属性获取唯一的实体
     * 
     * @param propertyName
     *            属性名称
     *@param value
     *            属性值
     */
    @SuppressWarnings("unchecked")
    @Override
    public T findUniqueByProperty(String propertyName, Object value) {
        Assert.hasText(propertyName, "propertyName不能为空");
        Criterion criterion = Restrictions.eq(propertyName, value);
        return (T) createCriteria(criterion).uniqueResult();
    }

    /**
     * 创建criteria的公共方法
     * 
     * @param criterions
     *            可变的criterion参数列表
     * */
    private Criteria createCriteria(final Criterion... criterions) {
        Criteria criteria = getSession().createCriteria(entityClass);
        for (Criterion c : criterions) {
            criteria.add(c);
        }
        return criteria;
    }

    /**
     * 根据属性排序获取数据列表
     * 
     * @param orderConditons
     *            排序条件
     */

    @SuppressWarnings("unchecked")
    @Override
    public List<T> getAllByOrder(List<OrderCondition> orderConditions) {
        StringBuilder hql = new StringBuilder();
        hql.append("from " + getEntityClassSimpleName());

        hql.append(changePropertyAndOrderToHqlByFlag(false, null,
                orderConditions));

        return createQuery(hql.toString()).list();
    }

    private static String ConvertOrderConditionToHql(
            OrderCondition... orderConditions) {
        if (orderConditions == null || orderConditions.length == 0) {
            return "";
        }

        StringBuilder sb = new StringBuilder(" order by ");
        StringBuilder str = new StringBuilder();
        String regex = ".*\\$\\{[a-z A-Z]+[\\.[a-z A-Z]]*+\\}.*";
        
        for (OrderCondition orderCondition : orderConditions) {
            if (orderCondition.toString().isEmpty()) {
                continue;
            }

            String propertyName = orderCondition.getPropertyName()
                    .toLowerCase();

            if (propertyName.matches(regex)){
            	str.append(orderCondition.toString().replace("${", "_e.").replace("}", "")).append(",");
            }else if (propertyName.split("\\.").length == 2  // 如果属性名为当前实体引用属性的主键（目前用id结尾判断）
                    && propertyName.endsWith("id")) {
                str.append("_order.");
                str.append(orderCondition.toString()).append(",");
            } else {
                str.append("_e.");
                str.append(orderCondition.toString()).append(",");
            }
        }
        
        if (str.toString().trim().isEmpty()) {
            return "";
        } else {
        	str.deleteCharAt(str.lastIndexOf(","));
            sb.append(str);
        }

        return sb.toString();
    }

    public static String ConvertOrderConditionToHql(
            List<OrderCondition> orderConditions) {
        if (orderConditions == null || orderConditions.isEmpty()) {
            return "";
        }
        //
        // StringBuilder sb = new StringBuilder(" order by ");
        // for (OrderCondition orderCondition : orderConditions) {
        // sb.append(orderCondition.toString()).append(" ").append(orderCondition.getOrder()).append(",");
        // }
        // sb.deleteCharAt(sb.lastIndexOf(","));
        OrderCondition[] ordCons = new OrderCondition[orderConditions.size()];
        return ConvertOrderConditionToHql(orderConditions.toArray(ordCons));
    }

    /**
     * 获取当前对象数组对应hql中的参数对象
     * 
     * @param conditions
     * @return
     */

    public static Map<String, Object> getNameHqlParam(
            PropertyFilter... conditions) {
        Map<String, Object> rslt = new HashMap<String, Object>();
        if (conditions == null || conditions.length == 0) {
            return null;
        }

        for (PropertyFilter propertyFilter : conditions) {
        	if (propertyFilter.getPropertyName() == null
        			|| propertyFilter.getPropertyName().isEmpty()){
        		continue;
        	}
        	
            String propertyNameValue = getPropertyName(propertyFilter)
                    + propertyFilter.hashCode();
            /* 此段程序提取为一个通用方法 getPropertyName(propertyFilter) edit by zhangds */
            // if (propertyFilter.getPropertyName() != null &&
            // propertyFilter.getPropertyName().indexOf(".") != -1) {
            // propertyNameValue = propertyFilter.getPropertyName().substring(0,
            // propertyFilter.getPropertyName().indexOf("."));
            // } else {
            // propertyNameValue = propertyFilter.getPropertyName();
            // }

            Object propertyValue = propertyFilter.getPropertyValue();

            if (propertyValue instanceof Date
                    && propertyFilter.getToCharFormat() != null
                    && !propertyFilter.getToCharFormat().isEmpty()) {
                propertyValue = DateTranslate.simpleDateTimeToString(
                        (Date) propertyValue, propertyFilter.getToCharFormat());
            }

            // 当操作符为between时，hql需要两个参数，通过比较两个参数的大小，将小的参数放在前面
            if (propertyFilter.getOperator().equals(OperatorType.BETWEEN)) {
                Boolean bChangePosition = false;

                Object propertyValue1 = propertyFilter.getPropertyValue1();

                if (propertyValue1 instanceof Date
                        && propertyFilter.getToCharFormat() != null
                        && !propertyFilter.getToCharFormat().isEmpty()) {
                    propertyValue1 = DateTranslate.simpleDateTimeToString(
                            (Date) propertyValue1, propertyFilter
                                    .getToCharFormat());
                }

                if (propertyFilter.getPropertyValueType().equalsIgnoreCase(
                        "Long")) {
                    bChangePosition = ((Long) (propertyFilter
                            .getPropertyValue()) > (Long) (propertyFilter
                            .getPropertyValue1()));
                } else if (propertyFilter.getPropertyValueType()
                        .equalsIgnoreCase("Date")) {
                    bChangePosition = ((Date) (propertyFilter
                            .getPropertyValue())).after((Date) (propertyFilter
                            .getPropertyValue1()));
                } else {
                    bChangePosition = propertyFilter.getPropertyValue()
                            .hashCode() > propertyFilter.getPropertyValue1()
                            .hashCode();
                }

                if (bChangePosition == false) {
                    rslt.put(propertyNameValue + "1", propertyValue);
                    rslt.put(propertyNameValue + "2", propertyValue1);

                } else {
                    rslt.put(propertyNameValue + "1", propertyValue1);
                    rslt.put(propertyNameValue + "2", propertyValue);
                }
            } else { // 当操作符不为between时，hql需要一个参数
                if (propertyFilter.getOperator().equals(OperatorType.LIKE)) {
                    String value = propertyValue.toString();
                    String escapeValue = value.replaceAll("[\\\\]", "\\\\\\\\");
                    escapeValue = escapeValue.replaceAll("[%]", "\\\\%");
                    escapeValue = escapeValue.replaceAll("[_]", "\\\\_");
                    rslt.put(propertyNameValue, "%" + escapeValue + "%");
                } else {
                    rslt.put(propertyNameValue, propertyValue);
                }
            }
        }
        return rslt;
    }

    /**
     * 获取当前对象数组对应hql中的参数对象
     * 
     * @param conditions
     * @return
     */
    public static Object[] getHqlParam(PropertyFilter... conditions) {
        List<Object> rslt = new ArrayList<Object>();
        if (conditions == null || conditions.length == 0) {
            return null;
        }

        for (PropertyFilter propertyFilter : conditions) {

        	if (propertyFilter.getPropertyName() == null
        			|| propertyFilter.getPropertyName().isEmpty()){
        		continue;
        	}
        	
            Object propertyValue = propertyFilter.getPropertyValue();

            if (propertyValue instanceof Date
                    && propertyFilter.getToCharFormat() != null
                    && !propertyFilter.getToCharFormat().isEmpty()) {
                propertyValue = DateTranslate.simpleDateTimeToString(
                        (Date) propertyValue, propertyFilter.getToCharFormat());
            }

            // 当操作符为between时，hql需要两个参数，通过比较两个参数的大小，将小的参数放在前面
            if (propertyFilter.getOperator().equals(OperatorType.BETWEEN)) {
                Object propertyValue1 = propertyFilter.getPropertyValue1();

                if (propertyValue1 instanceof Date
                        && propertyFilter.getToCharFormat() != null
                        && !propertyFilter.getToCharFormat().isEmpty()) {
                    propertyValue1 = DateTranslate.simpleDateTimeToString(
                            (Date) propertyValue1, propertyFilter
                                    .getToCharFormat());
                }

                Boolean bChangePosition = false;
                if (propertyFilter.getPropertyValueType().equalsIgnoreCase(
                        "Long")) {
                    bChangePosition = ((Long) (propertyFilter
                            .getPropertyValue()) > (Long) (propertyFilter
                            .getPropertyValue1()));
                } else if (propertyFilter.getPropertyValueType()
                        .equalsIgnoreCase("Date")) {
                    bChangePosition = ((Date) (propertyFilter
                            .getPropertyValue())).after((Date) (propertyFilter
                            .getPropertyValue1()));
                } else {
                    bChangePosition = propertyFilter.getPropertyValue()
                            .hashCode() > propertyFilter.getPropertyValue1()
                            .hashCode();
                }
                if (bChangePosition == false) {
                    rslt.add(propertyValue);
                    rslt.add(propertyValue1);
                } else {
                    rslt.add(propertyValue1);
                    rslt.add(propertyValue);
                }
            } else { // 当操作符不为between时，hql需要一个参数
                if (propertyFilter.getOperator().equals(OperatorType.LIKE)) {
                    String value = propertyValue.toString();
                    String escapeValue = value.replaceAll("[\\\\]", "\\\\\\\\");
                    escapeValue = escapeValue.replaceAll("[%]", "\\\\%");
                    escapeValue = escapeValue.replaceAll("[_]", "\\\\_");
                    rslt.add("%" + escapeValue + "%");
                } else {
                    rslt.add(propertyValue);
                }
            }
        }
        return rslt.toArray();
    }

    /**
     * 将当前对象数组转换成Hql语句,条件为?形式
     * 
     * @param conditions
     * @return
     */
    public static String changePropertyFiltersToHql(
            PropertyFilter... conditions) {
        return changePropertyFiltersToHqlByFlag(false, conditions);
    }

    /**
     * 将当前对象数组转换成Hql语句,条件为name形式
     * 
     * @param conditions
     * @return
     */
    /*
     * 添加对"Or"的支持 修改信息：zhangds
     */
    public static String changePropertyFiltersToNameHql(
            PropertyFilter... conditions) {
        return changePropertyFiltersToHqlByFlag(true, conditions);
    }

    public static String changePropertyFiltersToNameHql(
            List<PropertyFilter> conditions) {
        return changePropertyAndOrderToHqlByFlag(true, conditions, null);
    }

    public static Map<String, String> getMulTableAssociateFromProperty(
            List<PropertyFilter> propertyFilters, Map<String, String> joinAlias) {

        int joinEntityNum = 0;
        if (joinAlias == null) {
            joinAlias = new HashMap<String, String>();
        }

        if (propertyFilters != null && !propertyFilters.isEmpty()) {

            // 生成查询条件及查询条件涉及的多表关联语句
            for (PropertyFilter propertyFilter : propertyFilters) {
                String searchProperty = propertyFilter.getPropertyName();
                String eName = "_e";
                String[] joinEntity = searchProperty.split("\\.");
                joinEntityNum = 0;
                for (int i = 0; i < joinEntity.length - 1; i++) {
                    if (joinAlias.containsKey(eName + "." + joinEntity[i])) {
                        eName = joinAlias.get(eName + "." + joinEntity[i]);
                        continue;
                    } else {
                        String thisJoinName = "_e" + joinEntityNum;
                        while (joinAlias.containsValue(thisJoinName)) {
                            joinEntityNum++;
                            thisJoinName = "_e" + joinEntityNum;
                        }

                        joinAlias
                                .put(eName + "." + joinEntity[i], thisJoinName);
                        eName = thisJoinName;
                        joinEntityNum++;
                    }
                }

                String regex = "\\$\\{[a-z A-Z]+[\\.[a-z A-Z]]*+\\}";

                if (propertyFilter.getPropertyValueTypeEnum().equals(
                        ParamValueType.STRING)
                        && propertyFilter.getPropertyValue() != null
                        && propertyFilter.getPropertyValue().toString()
                                .matches(regex)) {
                    searchProperty = propertyFilter.getPropertyValue()
                            .toString();
                    searchProperty = searchProperty.substring(2, searchProperty
                            .lastIndexOf("}"));
                    eName = "_e";
                    joinEntity = searchProperty.split("\\.");
                    joinEntityNum = 0;
                    for (int i = 0; i < joinEntity.length - 1; i++) {
                        if (joinAlias.containsKey(eName + "." + joinEntity[i])) {
                            eName = joinAlias.get(eName + "." + joinEntity[i]);
                            continue;
                        } else {
                            String thisJoinName = "_e" + joinEntityNum;
                            while (joinAlias.containsValue(thisJoinName)) {
                                joinEntityNum++;
                                thisJoinName = "_e" + joinEntityNum;
                            }

                            joinAlias.put(eName + "." + joinEntity[i],
                                    thisJoinName);
                            eName = thisJoinName;
                            joinEntityNum++;
                        }
                    }
                }

                if (propertyFilter.getOperator().equals(OperatorType.BETWEEN)) {
                    if (propertyFilter.getPropertyValueTypeEnum().equals(
                            ParamValueType.STRING)
                            && propertyFilter.getPropertyValue1() != null
                            && propertyFilter.getPropertyValue1().toString()
                                    .matches(regex)) {
                        searchProperty = propertyFilter.getPropertyValue1()
                                .toString();
                        searchProperty = searchProperty.substring(2,
                                searchProperty.lastIndexOf("}"));
                        eName = "_e";
                        joinEntity = searchProperty.split("\\.");
                        joinEntityNum = 0;
                        for (int i = 0; i < joinEntity.length - 1; i++) {
                            if (joinAlias.containsKey(eName + "."
                                    + joinEntity[i])) {
                                eName = joinAlias.get(eName + "."
                                        + joinEntity[i]);
                                continue;
                            } else {
                                String thisJoinName = "_e" + joinEntityNum;
                                while (joinAlias.containsValue(thisJoinName)) {
                                    joinEntityNum++;
                                    thisJoinName = "_e" + joinEntityNum;
                                }

                                joinAlias.put(eName + "." + joinEntity[i],
                                        thisJoinName);
                                eName = thisJoinName;
                                joinEntityNum++;
                            }
                        }
                    }
                }

                joinAlias.putAll(getMulTableAssociateFromProperty(
                        propertyFilter.getAndFilters(), joinAlias));

                joinAlias.putAll(getMulTableAssociateFromProperty(
                        propertyFilter.getOrFilters(), joinAlias));
            }
        }

        return joinAlias;
    }

    public String getEntireHqlByPropertyAndOrder(Boolean isNameHql,
            List<PropertyFilter> propertyFilters,
            List<OrderCondition> orderConditions) {

        StringBuilder selectHql = new StringBuilder(); // 最终返回语句
        StringBuilder searchHql = new StringBuilder(); // 查询条件语句
        StringBuilder joinHql = new StringBuilder(); // 多表关联语句（统一使用left join）
        StringBuilder orderHql = new StringBuilder(); // 排序语句

        if (propertyFilters != null && !propertyFilters.isEmpty()) {
            searchHql.append(" where ");

            // 生成查询条件及查询条件涉及的多表关联语句
            for (PropertyFilter propertyFilter : propertyFilters) {
                if (isNameHql) {
                    searchHql.append(getNameHql2(propertyFilter));
                } else {
                    searchHql.append(getHql2(propertyFilter));
                }

                searchHql.append(" and ");
            }
            searchHql.delete(searchHql.length() - " and ".length(), searchHql
                    .length() - 1);
        }

        if (orderConditions != null && !orderConditions.isEmpty()) {
            orderHql.append(ConvertOrderConditionToHql(orderConditions));
        }

        Map<String, String> joinAlias = new HashMap<String, String>();

        joinAlias = getMulTableAssociateFromOrder(orderConditions, joinAlias);
        
//        selectHql.append("select distinct _e");
//        for (String key : joinAlias.keySet()) {
//            selectHql.append(",").append(joinAlias.get(key));
//        }
//        selectHql.append(" from ").append(entityClassSimpleName);
        
        joinAlias = getMulTableAssociateFromProperty(propertyFilters, joinAlias);

        joinHql.append(" _e");
        String searchStr = searchHql.toString();
        String orderStr = orderHql.toString();
        List<String> keySequence = new ArrayList<String>();

        // 对生成的Map进行排序
        for (String key : joinAlias.keySet()) {
            int i = keySequence.size();
            for (String s : keySequence) {
                if (joinAlias.get(s).length() > joinAlias.get(key).length()) {
                    i = keySequence.indexOf(s);
                    break;
                } else if (joinAlias.get(s).hashCode() > joinAlias.get(key)
                        .hashCode()) {
                    i = keySequence.indexOf(s);
                    break;
                }
            }
            keySequence.add(i, key);
        }

        // selectHql.append("select ");
        // for (String propertyName :
        // getSessionFactory().getClassMetadata(entityClass).getPropertyNames()){
        // selectHql.append("_t.").append(propertyName).append(",");
        // }
        // selectHql.deleteCharAt(selectHql.lastIndexOf(","));
        // selectHql.append(" from (");

        // 进行排序的字段，必须是 select项
        String selectStr = getMulTableSelectHqlFromOrder(orderConditions);
        
        for (String key : keySequence) {
            joinHql.append(" left join ").append(key).append(" ").append(
                    joinAlias.get(key));
            
            selectStr = selectStr.replace(key + ".", joinAlias.get(key) + ".");
            searchStr = searchStr.replace(key + ".", joinAlias.get(key) + ".");
            orderStr = orderStr.replace(key + ".", joinAlias.get(key) + ".");
        }

        // 将order by 中以Id结尾的部分替换
        orderStr = orderStr.replace("_order", "_e");
        
        selectHql.append(selectStr);
        joinHql.append(searchStr);
        joinHql.append(orderStr);
        selectHql.append(joinHql);
        // selectHql.append(") _t");
        return selectHql.toString();
    }

    private String getMulTableSelectHqlFromOrder(List<OrderCondition> orderConditions) {
    	
    	StringBuilder selectHql = new StringBuilder();
    	selectHql.append("select distinct _e");
    	
		if (orderConditions != null && !orderConditions.isEmpty()) {
			String regex = ".*\\$\\{[a-z A-Z]+[\\.[a-z A-Z]]*+\\}.*";

			// 生成排序条件及排序条件涉及的多表关联语句
			for (OrderCondition orderCondition : orderConditions) {
				if (orderCondition.toString().isEmpty()) {
	                continue;
	            }
				selectHql.append(",");
	            String propertyName = orderCondition.getPropertyName();
	            if (propertyName.matches(regex)){
	            	selectHql.append(propertyName.replace("${", "_e.").replace("}", ""));
	            }else if (propertyName.split("\\.").length == 2
	                    && propertyName.endsWith("id")) {
	            	// 如果属性名为当前实体引用属性的主键（目前用id结尾判断）
	            	//selectHql.append("");
	            } else {
	            	selectHql.append("_e.").append(propertyName);
	            }
			}
		}

        selectHql.append(" from ").append(entityClassSimpleName);
		return selectHql.toString();
	}

	private Map<String, String> getMulTableAssociateFromOrder(
			List<OrderCondition> orderConditions, Map<String, String> joinAlias) {

		if (joinAlias == null) {
			joinAlias = new HashMap<String, String>();
		}

		int joinEntityNum;
		if (orderConditions != null && !orderConditions.isEmpty()) {
			String regex = ".*\\$\\{[a-z A-Z]+[\\.[a-z A-Z]]*+\\}.*";

			// 生成排序条件及排序条件涉及的多表关联语句
			for (OrderCondition orderCondition : orderConditions) {
				String wholeOrderProperty = orderCondition.getPropertyName();
				String orderProperty = "";
				do {
					if (!wholeOrderProperty.matches(regex)){
						orderProperty = wholeOrderProperty;
					}else{
						orderProperty = StringUtils.substringAfter(
								wholeOrderProperty, "${");
						orderProperty = StringUtils.substringBefore(orderProperty,
								"}");
						wholeOrderProperty = StringUtils.substringAfter(
								wholeOrderProperty, "}");
					}

					String eName = "_e";
					String[] joinEntity = orderProperty.split("\\.");
					joinEntityNum = 0;
					for (int i = 0; i < joinEntity.length - 1; i++) {
						if (joinAlias.containsKey(eName + "." + joinEntity[i])) {
							eName = joinAlias.get(eName + "." + joinEntity[i]);
							continue;
						} else {
							String thisJoinName = "_e" + joinEntityNum;
							while (joinAlias.containsValue(thisJoinName)) {
								joinEntityNum++;
								thisJoinName = "_e" + joinEntityNum;
							}

							joinAlias.put(eName + "." + joinEntity[i],
									thisJoinName);
							eName = thisJoinName;
							joinEntityNum++;
						}
					}
				} while (wholeOrderProperty.matches(regex));
			}
		}
		return joinAlias;
	}
    
    public static String changePropertyAndOrderToHqlByFlag(Boolean isNameHql,
            List<PropertyFilter> propertyFilters,
            List<OrderCondition> orderConditions) {

        StringBuilder searchHql = new StringBuilder(); // 查询条件语句
        StringBuilder joinHql = new StringBuilder(); // 多表关联语句（统一使用left join）
        StringBuilder orderHql = new StringBuilder(); // 排序语句

        if (propertyFilters != null && !propertyFilters.isEmpty()) {
            searchHql.append(" where ");

            // 生成查询条件及查询条件涉及的多表关联语句
            for (PropertyFilter propertyFilter : propertyFilters) {
                if (isNameHql) {
                    searchHql.append(getNameHql2(propertyFilter));
                } else {
                    searchHql.append(getHql2(propertyFilter));
                }

                searchHql.append(" and ");
            }
            searchHql.delete(searchHql.length() - " and ".length(), searchHql
                    .length() - 1);
        }

        if (orderConditions != null && !orderConditions.isEmpty()) {
            orderHql.append(ConvertOrderConditionToHql(orderConditions));
        }

        Map<String, String> joinAlias = new HashMap<String, String>();
        joinAlias = getMulTableAssociateFromProperty(propertyFilters, joinAlias);

        joinHql.append(" _e");
        String searchStr = searchHql.toString();
        String orderStr = orderHql.toString();
        List<String> keySequence = new ArrayList<String>();

        // 对生成的Map进行排序
        for (String key : joinAlias.keySet()) {
            int i = keySequence.size();
            for (String s : keySequence) {
                if (joinAlias.get(s).length() > joinAlias.get(key).length()) {
                    i = keySequence.indexOf(s);
                    break;
                } else if (joinAlias.get(s).hashCode() > joinAlias.get(key)
                        .hashCode()) {
                    i = keySequence.indexOf(s);
                    break;
                }
            }
            keySequence.add(i, key);
        }

        for (String key : keySequence) {
            joinHql.append(" left join ").append(key).append(" ").append(
                    joinAlias.get(key));
            searchStr = searchStr.replace(key + ".", joinAlias.get(key) + ".");
            orderStr = orderStr.replace(key + ".", joinAlias.get(key) + ".");
        }

        // 将order by 中以Id结尾的部分替换
        orderStr = orderStr.replace("_order", "_e");

        joinHql.append(searchStr);
        joinHql.append(orderStr);
        return joinHql.toString();
    }

    private static String changePropertyFiltersToHqlByFlag(Boolean isNameHql,
            PropertyFilter... conditions) {
        if (conditions == null || conditions.length == 0) {
            return "";
        }
        List<PropertyFilter> propertyFilters = new ArrayList<PropertyFilter>();

        for (PropertyFilter propertyFilter : conditions) {
            propertyFilters.add(propertyFilter);
        }

        return changePropertyAndOrderToHqlByFlag(isNameHql, propertyFilters,
                null);
    }

    /**
     * 获得检索条件对应的hql语句,其中hql参数使用?表示 gt,ge,eq,lt,le,like,btween,ne,
     * isEmpty,isNull,isNotEmpty,isNotNull
     * 
     * @return
     */
    /**
     * edit by zhangds 2010-10-27 修改了生成hql语句'='赋值参数名称
     * */
    private static String getHql(PropertyFilter propertyFilter) {
        StringBuilder hql = new StringBuilder();

        String paramName = "?";
        
        if (propertyFilter == null 
        		|| propertyFilter.getPropertyName() == null
        		|| propertyFilter.getPropertyName().isEmpty()){
        	return "";
        } else if (propertyFilter.getPropertyName().equals("#hql")) {// 对#hql特殊处理
            return getRuleHql(hql, propertyFilter);
        }
        String regex = "\\$\\{[a-z A-Z]+[\\.[a-z A-Z]]*+\\}";

        //两列间运算标记
        Boolean isColsOperater = false;
        if (!propertyFilter.getOperator().equals(OperatorType.BETWEEN)) {
            if (propertyFilter.getPropertyValueTypeEnum().equals(
                    ParamValueType.STRING)
                    && propertyFilter.getPropertyValue() != null
                    && propertyFilter.getPropertyValue().toString().matches(
                            regex)) {
            	isColsOperater = true; //是两列间运算
                paramName = propertyFilter.getPropertyValue().toString();
                paramName = "_e." + paramName.substring(2, paramName.lastIndexOf("}"));
            }

            if (propertyFilter.getToCharFormat() == null
            		|| propertyFilter.getToCharFormat().isEmpty()) {
                hql.append("_e.").append(propertyFilter.getPropertyName());
            } else if (propertyFilter.getToCharFormat()
                    .equalsIgnoreCase("none")) {
                hql.append("to_char(_e.").append(propertyFilter.getPropertyName());
                hql.append(")");
                
                if (isColsOperater){//两列间 运算
                	paramName = propertyFilter.getPropertyValue().toString();
                    paramName = "to_char(_e." + paramName.replace("${", "").replace("}", "") + ")";
                }
            } else {
                hql.append("to_char(_e.").append(propertyFilter.getPropertyName());
                hql.append(",'").append(propertyFilter.getToCharFormat()).append("'");
                hql.append(")");
                
                if (isColsOperater){//两列间 运算 同时对两列进行格式化
                	paramName = propertyFilter.getPropertyValue().toString();
                    paramName = "to_char(_e." 
                    	+ paramName.replace("${", "").replace("}", "") 
                    	+ ",'" + propertyFilter.getToCharFormat()
                    	+ "')";
                }
            }
        }

        if (propertyFilter.getOperator() == null) {
            hql.append("=").append(paramName);
        } else if (propertyFilter.getOperator().equals(OperatorType.IN)) {
            Assert.notNull(propertyFilter.getPropertyValue(), "比较值不能为null!");
            hql.append(" in (").append(paramName).append(")");
        } else if (propertyFilter.getOperator().equals(OperatorType.GT)) {
            Assert.notNull(propertyFilter.getPropertyValue(), "比较值不能为null!");
            hql.append(">").append(paramName);
        } else if (propertyFilter.getOperator().equals(OperatorType.GE)) {
            Assert.notNull(propertyFilter.getPropertyValue(), "比较值不能为null!");
            hql.append(">=").append(paramName);
        } else if (propertyFilter.getOperator().equals(OperatorType.EQ)) {
            Assert.notNull(propertyFilter.getPropertyValue(),
                    "比较值不能为null，建议改用isNull!");
            hql.append("=").append(paramName);
        } else if (propertyFilter.getOperator().equals(OperatorType.LT)) {
            Assert.notNull(propertyFilter.getPropertyValue(), "比较值不能为null!");
            hql.append("<").append(paramName);
        } else if (propertyFilter.getOperator().equals(OperatorType.LE)) {
            Assert.notNull(propertyFilter.getPropertyValue(), "比较值不能为null!");
            hql.append("<=").append(paramName);
        } else if (propertyFilter.getOperator().equals(OperatorType.LIKE)) {
            Assert.notNull(propertyFilter.getPropertyValue(), "比较值不能为null!");
            hql.append(" like ").append(paramName);

            // like sql保留字转换，2011-01-12------------Rxh----------
            String value = propertyFilter.getPropertyValue().toString();
            if (value.matches(".*[\\%\\_]+.*")) {
                hql.append(" escape '\\'");
            }
        } else if (propertyFilter.getOperator().equals(OperatorType.BETWEEN)) {
            Assert.notNull(propertyFilter.getPropertyValue(),
                    "比较值value1不能为null!");
            Assert.notNull(propertyFilter.getPropertyValue1(),
                    "比较值value2不能为null!");

            paramName = "?";
            String paramName2 = "?";

            if (propertyFilter.getPropertyValueTypeEnum().equals(
                    ParamValueType.STRING)) {
                if (propertyFilter.getPropertyValue().toString().matches(regex)) {
                    paramName = propertyFilter.getPropertyValue().toString();
                    paramName = "_e."
                            + paramName
                                    .substring(2, paramName.lastIndexOf("}"));
                }

                if (propertyFilter.getPropertyValue1().toString()
                        .matches(regex)) {
                    paramName2 = propertyFilter.getPropertyValue().toString();
                    paramName2 = "_e."
                            + paramName2.substring(2, paramName2
                                    .lastIndexOf("}"));
                }
            }

            hql.append("_e.").append(propertyFilter.getPropertyName()).append(
                    " between ").append(paramName).append(" and  ").append(
                    paramName2);
        } else if (propertyFilter.getOperator().equals(OperatorType.NE)) {
            Assert.notNull(propertyFilter.getPropertyValue(),
                    "比较值不能为null，建议改用isNotNull!");
            hql.append("!=").append(paramName);
        } else if (propertyFilter.getOperator().equals(OperatorType.IS_NULL)) {
            hql.append(" is null ");
        } else if (propertyFilter.getOperator()
                .equals(OperatorType.IS_NOT_NULL)) {
            hql.append(" is not null ");
        } else if (propertyFilter.getOperator().equals(OperatorType.IS_EMPTY)) {
            hql.append(" is empty ");
        } else if (propertyFilter.getOperator().equals(
                OperatorType.IS_NOT_EMPTY)) {
            hql.append(" is not empty ");
        } else {
            hql.append("=").append(paramName);//
        }
        return hql.toString();
    }

    /**
     * 获得检索条件对应的hql语句,其中hql参数使用[:param]表示 gt,ge,eq,lt,le,like,btween,ne,
     * isEmpty,isNull,isNotEmpty,isNotNull
     * 
     * @return
     */
    private static String getNameHql(PropertyFilter propertyFilter) {
        StringBuilder hql = new StringBuilder();
        
        if (propertyFilter == null 
        		|| propertyFilter.getPropertyName() == null
        		|| propertyFilter.getPropertyName().isEmpty()){
        	return "";
        } else if (propertyFilter.getPropertyName().equals("#hql")) {// 对#hql特殊处理
            return getRuleHql(hql, propertyFilter);
        }
        String propertyNameValue = getPropertyName(propertyFilter);
        String paramName = ":" + propertyNameValue + propertyFilter.hashCode();

        String regex = "\\$\\{[a-z A-Z]+[\\.[a-z A-Z]]*+\\}";

        //两列间运算标记
        Boolean isColsOperater = false;
        
        if (!propertyFilter.getOperator().equals(OperatorType.BETWEEN)) {
            if (propertyFilter.getPropertyValueTypeEnum().equals(
                    ParamValueType.STRING)
                    && propertyFilter.getPropertyValue() != null
                    && propertyFilter.getPropertyValue().toString().matches(
                            regex)) {
            	isColsOperater = true; //是 两列间 运算
                paramName = propertyFilter.getPropertyValue().toString();
                paramName = "_e." + paramName.replace("${", "").replace("}", "");
            }
        }

        if (propertyFilter.getToCharFormat() == null
                || propertyFilter.getToCharFormat().isEmpty()) {
            hql.append("_e.").append(propertyFilter.getPropertyName());
        } else if (propertyFilter.getToCharFormat().equalsIgnoreCase("none")) {
            hql.append("to_char(_e.").append(propertyFilter.getPropertyName());
            hql.append(")");
            
            if (isColsOperater){//两列间 运算
            	paramName = propertyFilter.getPropertyValue().toString();
                paramName = "to_char(_e." + paramName.replace("${", "").replace("}", "") + ")";
            }
        } else {
            hql.append("to_char(_e.").append(propertyFilter.getPropertyName());
            hql.append(",'").append(propertyFilter.getToCharFormat()).append(
                    "'");
            hql.append(")");
            
            if (isColsOperater){//两列间 运算 同时对两列进行格式化
            	paramName = propertyFilter.getPropertyValue().toString();
                paramName = "to_char(_e." 
                	+ paramName.replace("${", "").replace("}", "") 
                	+ ",'" + propertyFilter.getToCharFormat()
                	+ "')";
            }
        }

        if (propertyFilter.getOperator() == null) {
            hql.append("=" + paramName);
        } else if (propertyFilter.getOperator().equals(OperatorType.IN)) {
            Assert.notNull(propertyFilter.getPropertyValue(), "比较值不能为null!");
            hql.append(" in (").append(paramName).append(")");
        } else if (propertyFilter.getOperator().equals(OperatorType.GT)) {
            Assert.notNull(propertyFilter.getPropertyValue(), propertyFilter
                    .getPropertyName()
                    + "比较值不能为null!");
            hql.append(">" + paramName);
        } else if (propertyFilter.getOperator().equals(OperatorType.GE)) {
            Assert.notNull(propertyFilter.getPropertyValue(), propertyFilter
                    .getPropertyName()
                    + "比较值不能为null!");
            hql.append(">=" + paramName);
        } else if (propertyFilter.getOperator().equals(OperatorType.EQ)) {
            Assert.notNull(propertyFilter.getPropertyValue(), propertyFilter
                    .getPropertyName()
                    + "比较值不能为null，建议改用isNull!");
            hql.append("=" + paramName);
        } else if (propertyFilter.getOperator().equals(OperatorType.LT)) {
            Assert.notNull(propertyFilter.getPropertyValue(), propertyFilter
                    .getPropertyName()
                    + "比较值不能为null!");
            hql.append("<" + paramName);
        } else if (propertyFilter.getOperator().equals(OperatorType.LE)) {
            Assert.notNull(propertyFilter.getPropertyValue(), propertyFilter
                    .getPropertyName()
                    + "比较值不能为null!");
            hql.append("<=" + paramName);
        } else if (propertyFilter.getOperator().equals(OperatorType.LIKE)) {
            Assert.notNull(propertyFilter.getPropertyValue(), propertyFilter
                    .getPropertyName()
                    + "比较值不能为null!");
            hql.append(" like ").append(paramName);
            String value = propertyFilter.getPropertyValue().toString();
            if (value.matches(".*[\\%\\_]+.*")) {
                hql.append(" escape '\\'");
            }
        } else if (propertyFilter.getOperator().equals(OperatorType.BETWEEN)) {
            Assert.notNull(propertyFilter.getPropertyValue(), propertyFilter
                    .getPropertyName()
                    + "比较值value1不能为null!");
            Assert.notNull(propertyFilter.getPropertyValue1(), propertyFilter
                    .getPropertyName()
                    + "比较值value2不能为null!");

            paramName = ":" + propertyNameValue + propertyFilter.hashCode()
                    + "1";
            String paramName2 = ":" + propertyNameValue
                    + propertyFilter.hashCode() + "2";

            hql.append(" between " + paramName + " and " + paramName2);
        } else if (propertyFilter.getOperator().equals(OperatorType.NE)) {
            Assert.notNull(propertyFilter.getPropertyValue(), propertyFilter
                    .getPropertyName()
                    + "比较值不能为null，建议改用isNotNull!");
            hql.append("!=" + paramName);
        } else if (propertyFilter.getOperator().equals(OperatorType.IS_NULL)) {
            hql.append(" is null");
        } else if (propertyFilter.getOperator()
                .equals(OperatorType.IS_NOT_NULL)) {
            hql.append(" is not null");
        } else if (propertyFilter.getOperator().equals(OperatorType.IS_EMPTY)) {
            hql.append(" is empty");
        } else if (propertyFilter.getOperator().equals(
                OperatorType.IS_NOT_EMPTY)) {
            hql.append(" is not empty");
        } else {
            hql.append("=" + paramName);
        }

        return hql.toString();
    }

    public void flush() {
        this.getSession().flush();
    }

    public void clearEntityOnSession(T entity) {
        this.getSession().evict(entity);
    }

    public void clearSession() {
        this.getSession().clear();
    }

    /**
     * 
     * @param queryName
     * @param orderConditions
     *            排序条件
     * @return
     */
    private Query getOrderByQuery(String queryName,
            List<OrderCondition> orderConditions) {
        Query query = getSession().getNamedQuery(queryName);
        StringBuilder strB = new StringBuilder(query.toString());

        if (null == orderConditions || orderConditions.isEmpty()) {
            return query;
        } else {
            strB.append(ConvertOrderConditionToHql(orderConditions));
            return getSession().createQuery(strB.toString());
        }
    }

    /**
     * 
     * @param queryName
     * @param orderConditions
     *            排序条件
     * @return
     */
    private Query getOrderByQuery(String queryName,
            OrderCondition... orderConditions) {
        Query query = getSession().getNamedQuery(queryName);
        StringBuilder strB = new StringBuilder(query.toString());

        if (null == orderConditions || orderConditions.length < 1) {
            return query;
        } else {
            strB.append(ConvertOrderConditionToHql(orderConditions));
            return getSession().createQuery(strB.toString());
        }
    }

    /* !----------------------支持or ----------------------------------- */
    /**
     * 此方法支持and ，or 形式的过滤条件 获得检索条件对应的hql语句,其中hql参数使用[:param]表示
     * */
    public static String getNameHql2(PropertyFilter pf) {
        String hql = "";
        hql = "(" + changePropertyToNamedHql(pf) + ")";
        return hql;
    }

    private static String changeAndPropertyToNamedHql(
            List<PropertyFilter> andList) {
        String andStr = "";
        if (andList.size() == 0) {
            return andStr;
        }
        for (PropertyFilter andFilter : andList) {
            String pfStr = changePropertyToNamedHql(andFilter);
            pfStr = pfStr + " and ";
            andStr = andStr + pfStr;
        }

        if (andStr.trim().endsWith("and")) {
            andStr = andStr.substring(0, andStr.lastIndexOf("and"));
        }

        andStr = "(" + andStr.trim() + ")";

        return andStr;
    }

    // private static String checkPropertyStr(String beforResult ,String
    // toBeAppending){
    // Pattern p = Pattern.compile("\\w+\\:\\w+");
    // Matcher m = p.matcher(toBeAppending);
    // while(m.find()){
    // String propStr =m.group();
    // String matcherStr =propStr;
    // //如果前面的条件语句已经包含同样的语句
    // while(beforResult.contains(matcherStr)){
    // matcherStr = matcherStr+"_1"; //
    // }
    // toBeAppending = toBeAppending.replace(propStr, matcherStr);
    // }
    // return toBeAppending;
    // }

    private static String changePropertyToNamedHql(PropertyFilter propertyFilter) {
        String result = "";
        if (propertyFilter == null) {
            return result;
        }

        result = getNameHql(propertyFilter);
        // 处理and
        String andStr = changeAndPropertyToNamedHql(propertyFilter
                .getAndFilters());
        if (!"".equalsIgnoreCase(andStr)) {
            // andStr =checkPropertyStr(result,andStr);
            result = result + " and " + andStr;
        }

        // 处理or
        String orStr = changeOrPropertyToNamedHql(propertyFilter.getOrFilters());
        if (!"".equalsIgnoreCase(orStr)) {
            // orStr =checkPropertyStr(result,orStr);
            result = result + " or " + orStr;
            result.trim();
        }

        return result.trim();
    }

    private static String changeOrPropertyToNamedHql(List<PropertyFilter> orList) {
        String orStr = "";
        if (orList.size() == 0)
            return orStr;
        // result ="(" + changeAndPropertyToNamedHql(propertyFilter).trim() +
        // " or " ;

        for (PropertyFilter orfilter : orList) {
            String pfStr = changePropertyToNamedHql(orfilter) + " or ";
            // pfStr =checkPropertyStr(orStr,pfStr);
            orStr = orStr + pfStr;
        }
        if (orStr.trim().endsWith("or")) {
            orStr = orStr.substring(0, orStr.lastIndexOf("or"));
        }

        return orStr.trim();
    }

    /**
     * 此方法支持and ，or 形式的过滤条件 获得检索条件对应的hql语句,其中hql参数使用[:?]表示
     * */
    public static String getHql2(PropertyFilter pf) {
        String result = "";
        List<PropertyFilter> orFilters = pf.getOrFilters();
        List<PropertyFilter> andFilters = pf.getAndFilters();

        if (andFilters.size() != 0) {
            for (PropertyFilter andFilter : andFilters) {
                result = result + getHql(andFilter);
            }

        }
        if (orFilters != null && orFilters.size() != 0) {
            result = "(" + getHql(pf) + " or ( ";
            for (PropertyFilter orfilter : orFilters) {
                result = result + getHql2(orfilter) + " and ";
            }
            if (result.trim().endsWith("and")) {
                result = result.substring(0, result.lastIndexOf("and"));
            }
            result = result + "))";

        } else {
            result = getHql(pf);
        }

        return result;
    }

    private static String getPropertyName(PropertyFilter propertyFilter) {
        String propertyNameValue = "";
        if (propertyFilter.getPropertyName() != null) {
            propertyNameValue = propertyFilter.getPropertyName().substring(
                    propertyFilter.getPropertyName().lastIndexOf(".") + 1);
        }

        return propertyNameValue;
    }

    /**
     * 提取PropertyFilter 集合的属性值，存放在一个map中
     * 
     * @param conditions
     * @return
     */
    public static Map<String, Object> getNameHqlParam2(
            PropertyFilter... conditions) {
        Map<String, Object> rslt = new HashMap<String, Object>();
        if (conditions == null)
            return rslt;
        for (PropertyFilter propertyFilter : conditions) {
            List<PropertyFilter> orFilters = propertyFilter.getOrFilters();
            List<PropertyFilter> andFilters = propertyFilter.getAndFilters();

            if (andFilters != null && andFilters.size() != 0) {
                for (PropertyFilter andFilter : andFilters) {
                    rslt.putAll(getNameHqlParam2(andFilter));
                }
                rslt.putAll(getNameHqlParam(propertyFilter));
            }
            if (orFilters != null && orFilters.size() != 0) {
                // rslt.putAll(getNameHqlParam(propertyFilter));
                // for (PropertyFilter orFilter : orFilters) {
                // Map<String,Object> orParams = getNameHqlParam2(orFilter);
                // //判断or中参数 是否重复，如果有重复加‘_1’
                // Set<Entry<String,Object>> entries = orParams.entrySet();
                // for (Entry<String, Object> entry : entries) {
                // String orParamName = entry.getKey();
                // while(rslt.containsKey(orParamName)){
                // orParamName = orParamName+"_1";
                // }
                // rslt.put(orParamName, entry.getValue());
                // }
                // }
                for (PropertyFilter orFilter : orFilters) {
                    rslt.putAll(getNameHqlParam2(orFilter));
                }
                rslt.putAll(getNameHqlParam(propertyFilter));// 放入原属性条件
            }
            if (andFilters.size() == 0 && orFilters.size() == 0) {
                rslt.putAll(getNameHqlParam(propertyFilter));
            }
        }
        return rslt;
    }

    // 获取一个特殊规则的hql
    private static String getRuleHql(StringBuilder hql,
            PropertyFilter propertyFilter) {
        hql.append(propertyFilter.getPropertyValue());
        return hql.toString();
    }
}
